// Header Protection
#ifndef _EVENT_H_
#define _EVENT_H_

// Forward Declaration
class ABCRegistration;

// Namespace
namespace IE
{
	/////////////////////////////////////////////////////////////////////////////////
	// Events are contained in classes and can be raised whenever necessary. When 
	//     an event is raised, all listeners which have registered for the event 
	//     receive the event arguments, and can process them whenever they are ready.
	template< class eventarg_t >
	class CEvent
	{
	public:     // methods
		inline CEvent() : m_RegistrationMutex(), m_lstpRegistrations() { }
		inline ~CEvent()
		{
#ifdef _DEBUG
			// make sure all listeners have been unregistered
			uint_t uRegCount = m_lstRegs.GetSize();
			for( uint_t i = 0; i < uRegCount; ++i )
			{
				assert( !m_lstRegs[i] );
			}
#endif // _DEBUG
		}

		// Raise the event. The argument will be passed to each registered handler.
		// _pArg : eventarg_t * - the argument to send to each handler
		void Raise( eventarg_t *_pArg );

	private:    // IListener friend methods
		friend class IListener;

		// Add a registration, associating a listener and event handler with 
		//     the event.
		// listener_t : template - the type of the listener
		// _pListener : listener_t - the event listener
		// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler
		template< class listener_t >
		void AddRegistration( 
			listener_t *_pListener, void (listener_t::*_pHandler)(eventarg_t &) );

		// Remove a registration with the given listener and event handler. If more 
		//     than one registration matches, the most recent is removed.
		// listener_t : template - the type of the listener
		// _pListener : listener_t - the event listener
		// _pHandler : void (listener_t::*)(eventarg_t &) - the event handler
		template< class listener_t >
		void RemoveRegistration( 
			listener_t *_pListener, void (listener_t::*_pHandler)(eventarg_t &) );

	private:    // data
		mutex_t                    m_RegistrationMutex;
		flist_t<ABCRegistration *> m_lstpRegistrations;

	private:    // dummy definitions
		CEvent( CEvent const & );
		CEvent &operator =( CEvent const & );
	};
}

// CEvent Template Implementation
#include "Event.hpp"

// Header Protection
#endif // _EVENT_H_
